//
//  CAIBehaviorStandardAttack.cpp
//  beast_tamer
//
//  Created by  bk on 13/2/24.
//
//

#include "CAIBehaviorStandardAttack.h"
#include "CBattleObject.h"
#include "CBattleManager.h"
#include "AnimationDef.h"
#include "CAIManager.h"
#include "CMonsterObject.h"
#include "CMemberCallback.h"

CAIBehaviorStandardAttack::CAIBehaviorStandardAttack():CAIBehavior(),CProcessFunctions(this)
{
    m_nCurrProcess = INVALID;
    
    m_targetObject = NULL;
    
    m_isStartTime = true;
    
    m_StartTime = 0;
}

CAIBehaviorStandardAttack::~CAIBehaviorStandardAttack()
{
    
}

bool CAIBehaviorStandardAttack::Init(CAIManager* ptr)
{
    if (ptr)
    {
        m_AiManager = ptr;
        
        
        Register(SEARCH,&CAIBehaviorStandardAttack::onProcessSearch);
        Register(MOVE,&CAIBehaviorStandardAttack::onProcessMove);
        Register(ATTACK,&CAIBehaviorStandardAttack::onProcessAttack);
        
        CCallBack* FunCallBack = new CMemberCallback<CAIBehaviorStandardAttack>(this,&CAIBehaviorStandardAttack::onHandleDamage);
        MyMaster()->RegisterAnimationCallBack(ACTIVE_ANIMATION_ID_ATTACK, FunCallBack);
        
        return true;
    }
    
    return false;
}

void CAIBehaviorStandardAttack::Entering(IStateInput*)
{
    MyMaster()->ChangeActiveAnimation(ACTIVE_ANIMATION_ID_IDLE);
    
    m_nCurrProcess = SEARCH;
    
    m_isStartTime = true;
}

void CAIBehaviorStandardAttack::Update(IStateInput* pInput)
{
    if (m_isStartTime)
    {
        
        m_StartTime += static_cast<CAiTimeInput*>(pInput)->dt;
    }
    
    processFun(m_nCurrProcess);
}

void CAIBehaviorStandardAttack::Leaving(IStateInput*)
{
    m_ShouldExit = false;
}

int CAIBehaviorStandardAttack::ShouldChange(IStateInput*)
{
    return INVALID;
}

void CAIBehaviorStandardAttack::onProcessSearch()
{
    if (m_StartTime < START_SEARCH_TIME)
    {
        
        return;
    }
    else
    {
        m_StartTime = 0 ;
        m_isStartTime = false;
    }
    
    int id = rand()%CBattleManager::Get().GetTeamMemberTotal(BATTLE_TEAM_RED);
    
    m_targetObject = CBattleManager::Get().GetTeamMember(BATTLE_TEAM_RED, id);
    
    CCAssert(m_targetObject, "m_targetObject can not null in function(CAIBehaviorStandardAttack::onProcessSearch)");
    
    m_nCurrProcess = MOVE;
    
    MyMaster()->ChangeActiveAnimation(ACTIVE_ANIMATION_ID_MOVE);
}

void CAIBehaviorStandardAttack::onProcessMove()
{
    if (!m_targetObject)
    {
        m_nCurrProcess = SEARCH;
    }
    
    if (MyMaster()->GetCurrActiveAnimation() != ACTIVE_ANIMATION_ID_MOVE)
    {
        MyMaster()->ChangeActiveAnimation(ACTIVE_ANIMATION_ID_MOVE);
        
        return;
    }
    
    
    fPoint targetPoint = HandleMoveCoodinate(m_targetObject->GetPoint());
    
    if(MyMaster()->GetPoint().Step(targetPoint, m_targetObject->GetPoint(), MOVELEN))
    {
        m_nCurrProcess = ATTACK;
        
        m_isStartTime = true;
        
        m_StartTime = 0;
        
        //
        MyMaster()->ChangeActiveAnimation(ACTIVE_ANIMATION_ID_IDLE);
    }
}

void CAIBehaviorStandardAttack::onProcessAttack()
{
    if (!m_targetObject)
    {
        m_nCurrProcess = SEARCH;
    }
    
    if (!m_isStartTime)
    {
        return;
    }
    else
    {
        if (m_StartTime < START_ATTACK_TIME)
        {
            if (MyMaster()->GetPoint().CheckDistance(m_targetObject->GetPoint(), ATTACK_DISTANCE_X+5) == false)
            {
                m_nCurrProcess = MOVE;
                
                MyMaster()->ChangeActiveAnimation(ACTIVE_ANIMATION_ID_MOVE);
            }
            
            return;
        }
        else
        {
            MyMaster()->ChangeActiveAnimation(ACTIVE_ANIMATION_ID_ATTACK);
            
            m_isStartTime = false;
            
            m_StartTime = 0;
            
            return;
        }
    }
    
}

fPoint CAIBehaviorStandardAttack::HandleMoveCoodinate(fPoint point)
{
    if (MyMaster()->GetPoint().X > point.X)
    {
        point.X += ATTACK_DISTANCE_X;
    }
    else
    {
        point.X -= ATTACK_DISTANCE_X;
    }
    
    point.Y += rand()%ATTACK_DISTANCE_Y;
    
    return point;
}

void CAIBehaviorStandardAttack::onHandleDamage(void* Data)
{
    if (m_targetObject->isDie())
    {
        m_nCurrProcess = SEARCH;
        
        m_targetObject = NULL;
        
        return;
    }
    
    
    m_isStartTime = true;
}

